package com.linq.cool.common.security.service;


import com.linq.cool.api.vo.WeChatLoginUser;
import com.linq.cool.common.constants.CacheConstants;
import com.linq.cool.common.constants.Constants;
import com.linq.cool.common.constants.UserConstants;
import com.linq.cool.common.core.utils.JwtUtils;
import com.linq.cool.common.core.utils.SecurityUtils;
import com.linq.cool.common.core.utils.ServletUtils;
import com.linq.cool.common.core.utils.StringUtils;
import com.linq.cool.common.redis.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Author: yqlin
 * @Date: 2020/12/29 16:12
 * @Description: token验证处理 微信小程序用户
 * @Version: 1.0.0
 */
@Component
public class WeChatTokenService {
    /**
     * 过期时间
     */
    private final static long EXPIRE_TIME = Constants.TOKEN_EXPIRE;
    /**
     * 访问token
     */
    private final static String ACCESS_TOKEN = CacheConstants.LOGIN_TOKEN_KEY;

    @Autowired
    private RedisService redisService;

    /**
     * 创建令牌
     */
    public Map<String, Object> createToken(WeChatLoginUser loginUser) {
        String token = JwtUtils.sign(loginUser.getUserId(), EXPIRE_TIME, UserConstants.StateEnum.LOGIN_TYPE_WECHAT.getCode());
        loginUser.setToken(token);
        this.refreshToken(loginUser);
        Map<String, Object> map = new HashMap<>(2);
        map.put("access_token", token);
        // 12 * 60  * 60  前端 720min
        map.put("expires_in", EXPIRE_TIME * 60);
        redisService.setCacheObject(ACCESS_TOKEN + token, loginUser, EXPIRE_TIME, TimeUnit.MINUTES);
        return map;
    }


    /**
     * 获取用户身份信息
     */
    public WeChatLoginUser getLoginUser() {
        return getLoginUser(ServletUtils.getRequest());
    }

    /**
     * 设置用户身份信息
     */
    public void setLoginUser(WeChatLoginUser loginUser) {
        if (StringUtils.isNotNull(loginUser) && StringUtils.isNotEmpty(loginUser.getToken())) {
            refreshToken(loginUser);
        }
    }

    public WeChatLoginUser getLoginUser(HttpServletRequest request) {
        // 获取请求携带的令牌
        String token = SecurityUtils.getToken(request);
        return StringUtils.isNotEmpty(token) ? redisService.getCacheObject(getTokenKey(token)) : null;
    }

    /**
     * 清除用户身份信息
     */
    public void removeLoginUser(String token) {
        if (StringUtils.isNotEmpty(token)) {
            redisService.deleteObject(getTokenKey(token));
        }
    }

    /**
     * 刷新令牌有效期
     */
    public void refreshToken(WeChatLoginUser loginUser) {
        loginUser.setLoginTime(System.currentTimeMillis())
                .setExpireTime(loginUser.getLoginTime() + EXPIRE_TIME * 60 * 1000);
        // 根据uuid将loginUser缓存
        String userKey = getTokenKey(loginUser.getToken());
        redisService.setCacheObject(userKey, loginUser, EXPIRE_TIME, TimeUnit.MINUTES);
    }

    private String getTokenKey(String token) {
        return ACCESS_TOKEN + token;
    }


}
